from twisted.internet import reactor, protocol
from twisted.protocols import basic
import time
import cardhand
import carddeck
import carddealer
import cPickle
import message

def t():
    return "["+ time.strftime("%H:%M:%S") +"] "

class EchoProtocol(basic.LineReceiver):
    name = "Unnamed"

    def connectionMade(self):
        self.sendLine("Welcome, what is your name?")
        self.sendLine("")
        self.count = 0
        self.factory.clients.append(self)
        print t() + "+ Connection from: "+ self.transport.getPeer().host

    def connectionLost(self, reason):
        self.sendMsg("- %s left." % self.name)
        print t() + "- Connection lost: "+ self.name
        self.factory.clients.remove(self)
        #names = []
        #for item in self.factory.clients:
        #    names.append(item.name)
        #self.sendMsg(cPickle.dumps(names))

    def lineReceived(self, line):
        # Determine if this is a pickled object (that should only be passed by buttonClick events)
        # or simply a chat string.
        try:
            undata = cPickle.loads(line) 
            if isinstance(undata, message.ClientsMessage):
                temp = undata.do
                if temp == 'deal':
                    sendHands = []
                    for client in self.factory.clients:
                        sendHands.append(cardhand.Hand(self.factory.deck.deal_card(),self.factory.deck.deal_card()))
                    print "Now sending {} hands.".format(len(sendHands))
                    # for hand in sendHands:
                    self.sendMsg(cPickle.dumps(sendHands))
                        # self.sendMsg(cPickle.dumps(hand,2))
                return
        except (cPickle.UnpicklingError,EOFError) as e:
            pass
    
        if line == 'quit':
            self.sendLine("Goodbye.")
            self.transport.loseConnection()
            return
        elif line == "userlist":
            self.chatters()
            return
        if not self.count:
            self.username(line)
        else:
            self.sendMsg(self.name +": " + line)

    def username(self, line):
        for x in self.factory.clients:
            if x.name == line:
                self.sendLine("This username is taken; please choose another")
                return

        self.name = line
        self.chatters()
        self.sendLine("Chat away!")
        self.sendLine("")
        self.count += 1
        self.sendMsg("+ %s joined." % self.name)
        print '%s~ %s is now known as %s' % (t(), self.transport.getPeer().host, self.name)
        #names = []
        #for item in self.factory.clients:
        #    names.append(item.name)
        #self.sendMsg(cPickle.dumps(names))

    def chatters(self):
        x = len(self.factory.clients)
        s = 'is' if x == 1 else 'are'
        p = 'person' if x == 1 else 'people'
        # self.sendLine(cPickle.dumps("There %s %i %s connected:" % (s, x, p)))
        self.sendLine("There %s %i %s connected:" % (s, x, p))

        for client in self.factory.clients:
            # if client is not self:
            self.sendLine(client.name)
        self.sendLine("")

    def sendMsg(self, message):
        for client in self.factory.clients:
            client.sendLine(message)


class EchoServerFactory(protocol.ServerFactory):
    protocol  = EchoProtocol
    clients = []
    deck = carddeck.Deck(carddeck.DECKSIZE)
    deck.shuffle()
    dealer = carddealer.Dealer()

if __name__ == "__main__":
    reactor.listenTCP(5001, EchoServerFactory())
    reactor.run()